﻿using System;
using System.ComponentModel.Composition;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ServiceLocatorAdapter;
using Mockery.Core.CommonContainer;

namespace CommonContainer.Mockery.Unity12
{
    [Export(typeof(ICommonContainerBuilder))]
    public class UnityContainerBuilder : ICommonContainerBuilder
    {
        private IUnityContainer _unityContainer;

        #region ctor

        public UnityContainerBuilder()
        {
            _unityContainer = new UnityContainer();
        }

        #endregion

        #region ICommonContainerBuilder Members

        /// <summary>
        /// Creates a new instance of the ContainerBuilder for quickly launching
        /// a new instance
        /// </summary>
        /// <returns>a new ContainerBuilder instance for Unity</returns>
        public ICommonContainerBuilder New()
        {
            return new UnityContainerBuilder();
        }

        /// <summary>
        /// Registers an instance as a sington for resolution purposes. This signature
        /// allows the registered type to differ from the instance
        /// </summary>
        /// <typeparam name="TType">type to register</typeparam>
        /// <param name="resolveType">type to be registered</param>
        /// <param name="instance">instance to be registerd</param>
        public void RegisterInstance<TType>(Type resolveType, TType instance)
        {
            _unityContainer.RegisterInstance(resolveType, instance);
        }

        /// <summary>
        /// Registers a type to be resolved as a singleton. This signature
        /// allows the registered type to differ from the instance type 
        /// according to relationship rule
        /// </summary>
        /// <typeparam name="TType">type to register</typeparam> 
        /// <typeparam name="TResolveType">instance type to register</typeparam>
        public void RegisterType<TType, TResolveType>() where TType : TResolveType
        {
            _unityContainer.RegisterType<TResolveType, TType>(new ContainerControlledLifetimeManager());
        }

        /// <summary>
        /// Registers a type to be resolved at runtime as a singleton
        /// </summary>
        /// <typeparam name="TType">type to be registered and retrieved</typeparam>
        public void RegisterType<TType>()
        {
            _unityContainer.RegisterType<TType, TType>(new ContainerControlledLifetimeManager());
        }

        /// <summary>
        /// Retrieves a common service locator for the underlying instance
        /// </summary>
        public IServiceLocator ServiceLocator
        {
            get { return new UnityServiceLocator(_unityContainer); }
        }

        #endregion
    }
}
